package com.qianfeng.openplatform.zuul.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.qianfeng.openplatform.common.BaseResultBean;
import com.qianfeng.openplatform.common.CommonsConstants;
import com.qianfeng.openplatform.common.Md5Util;
import com.qianfeng.openplatform.common.SystemParams;
import com.qianfeng.openplatform.zuul.feign.CacheFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.Map;
import java.util.TreeMap;

/**
 * @Author LJF
 * @Date 2020/8/6 17:45
 * @Version 1.0
 */
@Component
@Slf4j
public class SignFilter extends ZuulFilter {

    @Autowired
    private CacheFeign cacheFeign;

    @Autowired
    private ObjectMapper objectMapper;


    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 35;
    }

    @Override
    public boolean shouldFilter() {
        return RequestContext.getCurrentContext().sendZuulResponse();
    }

    @Override
    public Object run() throws ZuulException {
        //得到request对象
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        //获取所有的参数名称
        Enumeration<String> parameterNames = request.getParameterNames();
        //定义一个treeMap来装请求携带的参数
        Map<String, String> paramMap = new TreeMap<>();
        while (parameterNames.hasMoreElements()) {
            String parameterName = parameterNames.nextElement();
            //如果不是sign参数，都加入到treeMap中进行字典排序
            if (!"sign".equalsIgnoreCase(parameterName)) {
                paramMap.put(parameterName, request.getParameter(parameterName));
            }
        }
        try {
            //得到参数加携带的app_key
            String appKey = request.getParameter("appKey");
            //得到密钥
            String appSecret = cacheFeign.hGet(SystemParams.APPKEY_REDIS_PRE + appKey, "appSecret");
            //通过md5计算得到密钥
            String md5Signature = Md5Util.md5Signature(paramMap, appSecret);
            String sign = request.getParameter("sign");
            log.error("系统计算出来的签名：" + md5Signature);
            log.error("请求携带的签名：" + sign);
            if (md5Signature.equalsIgnoreCase(sign)) {
                //签名校验通过
                return null;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        //签名校验失败
        currentContext.setSendZuulResponse(false);
        BaseResultBean resultBean = new BaseResultBean();
        resultBean.setCode(CommonsConstants.PARAMETER_TIMESTAMP_ERROR);
        resultBean.setMsg("签名校验失败！！");
        currentContext.getResponse().setContentType("application/json;charset=utf-8");

        try {
            currentContext.setResponseBody(objectMapper.writeValueAsString(resultBean));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}
